#include "table.h"

#include "mem.h"

#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>

static void
test()
{
    Table_T table = Table_new(1000, NULL, NULL);
    assert(Table_length(table) == 0);
    Table_free(&table);
    assert(table == NULL);

    table = Table_new(1000, NULL, NULL);
    Table_put(table, (void*)100, "hello");
    assert(Table_length(table) == 1);
    assert(strcmp(Table_get(table, (void*)100), "hello") == 0);

    assert(strcmp(Table_remove(table, (void*)100), "hello") == 0);
    assert(Table_length(table) == 0);
    Table_free(&table);
    assert(table == NULL);
}

static void
test_put_get()
{
    Table_T table = Table_new(1000, NULL, NULL);
    Table_put(table, (void*)100, (void*)1000);
    Table_put(table, (void*)200, (void*)2000);
    Table_put(table, (void*)300, (void*)3000);

    assert(Table_get(table, (void*)300) == (void*)3000);

    assert(Table_remove(table, (void*)300) == (void*)3000);
    assert(Table_get(table, (void*)300) == NULL);
    assert(Table_remove(table, (void*)300) == NULL);

    assert(Table_length(table) == 2);
    assert(Table_get(table, (void*)100) == (void*)1000);

    Table_free(&table);
    assert(table == NULL);
}

static void
free_data(const void *key, void **value, void *cl)
{
    (void)key;
    (void)cl;
    free(*value);
}

static void
test_array()
{
    Table_T table = Table_new(1000, NULL, NULL);
    Table_put(table, (void*)100, (void*)1000);
    Table_put(table, (void*)200, (void*)2000);
    Table_put(table, (void*)300, (void*)3000);

    void **array = Table_toArray(table, NULL);
    int i;
    for (i = 0; array[i]; i += 2) {
        assert(Table_get(table, array[i]) == array[i + 1]);
    }
    assert(Table_length(table) == i/2);
    FREE(array);
}

static void
test_freeall()
{
    Table_T table = Table_new(1000, NULL, NULL);

    Table_put(table, (void*)100, malloc(4));
    Table_put(table, (void*)200, malloc(4));
    Table_put(table, (void*)300, malloc(4));

    Table_map(table, free_data, NULL);
    Table_free(&table);
    assert(table == NULL);
}

int main()
{
    test();
    test_put_get();
    test_array();
    test_freeall();
    return 0;
}
